home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_pcdp / ada / snap.ada < prev    next >
Text File  |  1996-01-30  |  5KB  |  184 lines

  1. with Semaphore_Package; use Semaphore_Package;
  2. with Text_IO; use Text_IO; 
  3. procedure Snap is
  4.  
  5.   type Node_Count is range 0..4;
  6.   subtype Node_ID is Node_Count range 1..Node_Count'Last;
  7.   Print: Binary_Semaphore := Init(1);
  8.  
  9.   task type Nodes is
  10.     entry Init(ID: Node_ID; N_I, N_O: Node_Count);
  11.     entry Configure(C: Node_ID);
  12.     entry Message(M: Integer; ID: Node_ID);
  13.   end Nodes;
  14.  
  15.   Node: array(Node_ID) of Nodes;
  16.  
  17.   task body Nodes is
  18.  
  19.     type Edge is
  20.       record
  21.         Exists:  Boolean := False;
  22.         Last_Message: Integer := 0;
  23.         Recorded_State: Integer := 0;
  24.         Marker_State:   Integer := -1;
  25.       end record;
  26.  
  27.     Incoming: array(Node_ID) of Edge;
  28.     Outgoing: array(Node_ID) of Edge;
  29.     N_In, N_Out: Node_Count := 0;
  30.     S: Binary_Semaphore := Init(1);
  31.     Received_ID: Node_ID;
  32.     Received_Data: Integer;
  33.     State_Recorded: Boolean := False;
  34.     I: Node_ID;
  35.  
  36.     pragma Volatile(Incoming);
  37.     pragma Volatile(State_Recorded);
  38.  
  39.     procedure Send_Messages(Data: Integer) is
  40.     begin
  41.       for J in Node_ID loop
  42.         if Outgoing(J).Exists then
  43.            Wait(S);
  44.            if Data >= 0 then
  45.              Outgoing(J).Last_Message := Data;
  46.            elsif not State_Recorded then
  47.              Outgoing(J).Recorded_State := Outgoing(J).Last_Message;
  48.            end if;
  49.            Signal(S);
  50.            Node(J).Message(Data, I);
  51.         end if;
  52.       end loop;
  53.     end Send_Messages;
  54.  
  55.     procedure Record_State is
  56.     begin
  57.       if not State_Recorded then
  58.         Wait(S);
  59.         for J in Node_ID loop
  60.           if Incoming(J).Exists then
  61.             Incoming(J).Recorded_State := Incoming(J).Last_Message;
  62.           end if;
  63.         end loop;
  64.         Signal(S);
  65.         Send_Messages(-1);
  66.         State_Recorded := True;
  67.       end if;
  68.     end Record_State;
  69.  
  70.     function Write_State return Boolean is
  71.     begin
  72.       if not State_Recorded then return False; end if;
  73.       for J in Node_ID loop
  74.         if Incoming(J).Exists and Incoming(J).Marker_State < 0 then
  75.           return False;
  76.         end if;
  77.       end loop;
  78.  
  79.       Wait(Print);
  80.       Put_Line(" Node " & Node_ID'Image(I) );
  81.       Put_Line("       Outgoing channels");
  82.       for J in Node_ID loop
  83.         if Outgoing(J).Exists then
  84.           Put_Line("         " & Node_ID'Image(J) & " sent 1.." &
  85.                    Integer'Image(Outgoing(J).Recorded_State));
  86.         end if;
  87.       end loop;
  88.  
  89.       Put_Line("       Incoming  channels");
  90.       for J in Node_ID loop
  91.         if Incoming(J).Exists then
  92.           Put("         " & Node_ID'Image(J) &
  93.             " received 1.." & Integer'Image(Incoming(J).Recorded_State));
  94.           if Incoming(J).Recorded_State /= Incoming(J).Marker_State then
  95.             Put_Line(" stored " & Integer'Image(Incoming(J).Recorded_State+1) &
  96.             " to " & Integer'Image(Incoming(J).Marker_State));
  97.           else
  98.            New_Line;
  99.          end if;
  100.         end if;
  101.       end loop;
  102.       Signal(Print);
  103.       return True;
  104.     end Write_State;
  105.  
  106.     task Main_Process is
  107.       entry Init;
  108.     end Main_Process;
  109.  
  110.     task body Main_Process is
  111.     begin
  112.       accept Init;
  113.       for J in 1..9 loop
  114.         Send_Messages(J);
  115.         case I is
  116.           when 2 | 3 => null;
  117.           when 1 => if J = 6 then Record_State; end if;
  118.           when 4 => if J = 3 then Record_State; end if;
  119.         end case;
  120.       end loop;
  121.       loop 
  122.         exit when Write_State; 
  123.         delay 0.01;
  124.       end loop;
  125.     end Main_Process;
  126.  
  127.   begin
  128.     accept Init(ID: Node_ID; N_I, N_O: Node_Count) do
  129.       I := ID;
  130.       N_In  := N_I;
  131.       N_Out := N_O;
  132.     end Init;
  133.     for J in 1..N_In loop
  134.       accept Configure(C: Node_ID) do
  135.         Incoming(C).Exists := True;
  136.       end Configure;
  137.     end loop;
  138.     for J in 1..N_Out loop
  139.       accept Configure(C: Node_ID) do
  140.         Outgoing(C).Exists := True;
  141.       end Configure;
  142.     end loop;
  143.  
  144.     Main_Process.Init;
  145.  
  146.     loop
  147.       select
  148.         accept Message(M: Integer; ID: Node_ID) do
  149.           Received_ID := ID;
  150.           Received_Data := M;
  151.         end Message;
  152.         if Received_Data < 0 then
  153.           if Incoming(Received_ID).Marker_State < 0 then
  154.             Incoming(Received_ID).Marker_State := 
  155.               Incoming(Received_ID).Last_Message;
  156.           if not State_Recorded then Record_State; end if;
  157.           end if;
  158.         else
  159.           Wait(S);
  160.           Incoming(Received_ID).Last_Message := Received_Data;
  161.           Signal(S);
  162.         end if;
  163.       or
  164.         terminate;
  165.       end select;
  166.     end loop;
  167.   end Nodes;
  168.  
  169. begin
  170.   Node(1).Init(1,0,2);
  171.   Node(1).Configure(2); Node(1).Configure(3);
  172.  
  173.   Node(2).Init(2,2,2);
  174.   Node(2).Configure(1); Node(2).Configure(3);
  175.   Node(2).Configure(3); Node(2).Configure(4);
  176.  
  177.   Node(3).Init(3,3,1); 
  178.   Node(3).Configure(1); Node(3).Configure(2);
  179.   Node(3).Configure(4); Node(3).Configure(2);
  180.  
  181.   Node(4).Init(4,1,1); 
  182.   Node(4).Configure(2); Node(4).Configure(3);
  183. end Snap;
  184.